package com.wry.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * <h1>  </h1>
 *
 * @author wry
 * @since 2025.04.15
 */
@RequestMapping("redis")
@RestController
public class RedisController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @GetMapping("zset-test")
    public String getZet() {

        String startTime = "2025-04-05 12:00:00";
        String endTime = "2025-04-05 12:30:00";
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", startTime, TimeUtil.toMilliSecond(startTime));
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", endTime, TimeUtil.toMilliSecond(endTime));

        String startTime1 = "2025-04-05 12:27:00";
        String endTime1 = "2025-04-05 12:31:00";
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", startTime1, TimeUtil.toMilliSecond(startTime1));
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", endTime1, TimeUtil.toMilliSecond(endTime1));

        String startTime2 = "2025-04-05 12:28:00";
        String endTime2 = "2025-04-05 12:32:00";
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", startTime2, TimeUtil.toMilliSecond(startTime2));
        redisTemplate.opsForZSet().add("KAOLA_PULL_ORDER_ERR_TIME_KEY", endTime2, TimeUtil.toMilliSecond(endTime2));


        String firstElement  = redisTemplate.opsForZSet().range("KAOLA_PULL_ORDER_ERR_TIME_KEY", 0, 0).iterator().next();
        String lastElement   = redisTemplate.opsForZSet().range("KAOLA_PULL_ORDER_ERR_TIME_KEY", -1, -1).iterator().next();

        return firstElement + "-" + lastElement;
    }

    @GetMapping("set-diff")
    public String setDiff() {
        String[] k1s = new String[10];
        for (int i = 0; i < 10; i++) {
            k1s[i] = i + "";
        }
        String[] k2s = new String[10];
        int index = 0;
        for (int i = 5; i < 15; i++) {
            k2s[index] = i + "";
            index++;
        }

        redisTemplate.opsForSet().add("k1", k1s);
        redisTemplate.opsForSet().add("k2", k2s);
        Set<String> difference = redisTemplate.opsForSet().difference("k1", "k2");
        System.out.println(difference);
        return "ok";
    }



    public static class LRUCache<K, V> extends LinkedHashMap<K, V> {
        private int cacheSize;

        public LRUCache(int cacheSize) {
            super(16, 0.75F, true);
            this.cacheSize = cacheSize;
        }
        //LinkedHashMap有一个removeEldestEntry(Map.Entry eldest)方法，通过覆盖这个方法，加入一定的条件，满足条件返回true。当put进新的值方法返回true时，便移除该map中最老的键和值。
        protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
            return size() >= cacheSize;
        }
    }

    public static void main(String[] args) {
        int[] arr = new int[]{1,5,6,10,15,26,27,30,45,100};
        System.out.println(binarySearch2(arr, 1));
    }

    public static int binarySearch(int[] arr, int num) {
        int low = 0;
        int high = arr.length - 1;
        while (high >= low) {
            int mid = low + (high - low) / 2;
            if (arr[mid] > num) {
                // 中间值比他大
                high = mid - 1;
            } else if (arr[mid] < num) {
                // 中间值比他小
                low = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

    public static int binarySearch2(int[] arr, int key) {
        int low = 0;
        int high = arr.length - 1;
        for (;;) {
            if (high < low) {
                break;
            }
            int mid = low + (high - low) / 2;
            if (arr[mid] > key) {
                high = mid - 1;
            } else if (arr[mid] < key) {
                low = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;


    }

    public static void cp(){
        List<CompletableFuture<Boolean>> completableFutureList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            CompletableFuture<Boolean> async = CompletableFuture.supplyAsync(() -> {
                return buyTicket();
            });
            completableFutureList.add(async);
        }
        List<Boolean> result = completableFutureList.stream()
                .map(CompletableFuture::join)
                .filter(b -> b)
                .collect(Collectors.toList());
    }

    private static synchronized Boolean buyTicket() {
        if (ticketNum > 0){
            return true;
        }
        return false;
    }

    private static volatile int ticketNum;


    public static class Instance {
        private  volatile static Instance instance;
        private Instance getInstance(){
            synchronized (Object.class) {
                if (instance == null) {
                    synchronized (Object.class) {
                        return new Instance();
                    }
                }
                return instance;
            }
        }
    }



}
